﻿#region 信息

// Copyright©2014 Rex Rao all rights reserved.
// File name : SoMcCoffee\Sohobloo.SoCommon\Logger.cs
// Author : Sohobloo
// Create time : 2014/02/07 9:07
// Update time : 2014/02/08 10:41

#endregion

#region 引用

using System;
using System.ComponentModel.Composition;
using System.Text;
using log4net;
using Sohobloo.SoCommon.CommonExtension;

#endregion

namespace Sohobloo.SoCommon.Log
{
    public class Logger : ILogger
    {
        internal static ILog CommonLogger;
        internal static ILog SqlTracer;
        private static readonly IOperator SystemLogOperator = new SystemLogOperator();

        [Import]
        protected IOperator LogOperator { get; set; }

        public void Info(object message)
        {
            var formattedMessage = Format(message, null, LogOperator);
            CommonLogger.Info(formattedMessage);
        }

        public void Error(object message)
        {
            var formattedMessage = Format(message, null, LogOperator);
            CommonLogger.Error(formattedMessage);
        }

        public void Error(Exception ex)
        {
            var formattedMessage = Format(null, ex, LogOperator);
            CommonLogger.Error(formattedMessage);
        }

        public void Error(object message, Exception ex)
        {
            var formattedMessage = Format(message, ex, LogOperator);
            CommonLogger.Error(formattedMessage);
        }

        public void Debug(object message)
        {
            var formattedMessage = Format(message, null, LogOperator);
            CommonLogger.Debug(formattedMessage);
        }

        public void TraceSql(object message)
        {
            if(SqlTracer.IsNotNull()
               && message.IsNotNull()
               && message.ToString().IsNotNullOrEmpty())
            {
                var formattedMessage = FormatSqlTrace(message, LogOperator);
                SqlTracer.Debug(formattedMessage);
            }
        }

        //public static void LogInfo(object message)
        //{
        //    LogInfo(message, null);
        //}

        public static void LogInfo(object message, IOperator logOperator)
        {
            var formattedMessage = Format(message, null, logOperator);
            CommonLogger.Info(formattedMessage);
        }

        //public static void LogError(object message)
        //{
        //    LogError(message, null, null);
        //}

        //public static void LogError(object message, IOperator logOperator)
        //{
        //    LogError(message, null, logOperator);
        //}

        //public static void LogError(Exception ex)
        //{
        //    LogError(null, ex, null);
        //}

        //public static void LogError(Exception ex, IOperator logOperator)
        //{
        //    LogError(null, ex, logOperator);
        //}

        //public static void LogError(object message, Exception ex)
        //{
        //    LogError(null, ex, null);
        //}

        public static void LogError(object message, Exception ex, IOperator logOperator)
        {
            var formattedMessage = Format(message, ex, logOperator);
            CommonLogger.Error(formattedMessage);
        }

        //public static void LogDebug(object message)
        //{
        //    LogDebug(message, null);
        //}

        public static void LogDebug(object message, IOperator logOperator)
        {
            var formattedMessage = Format(message, null, logOperator);
            CommonLogger.Debug(formattedMessage);
        }

        //public static void LogSql(object message)
        //{
        //    LogSql(message, null);
        //}

        //public static void TraceSql(object message, IOperator logOperator)
        //{
        //    var formattedMessage = Format(message, null, logOperator);
        //    SqlLogger.Debug(formattedMessage);
        //}

        private static string Format(object message, Exception ex, IOperator logOperator)
        {
            if(logOperator.IsNull())
            {
                logOperator = SystemLogOperator;
            }

            var sb = new StringBuilder()
                .AppendLine("----------START----------")
                .Append("[Time] ").AppendLine(DateTime.Now.ToString("HH:mm:ss.fff"))
                .Append("[Operator] ").AppendLine(logOperator.Name)
                .Append("[Message] ").AppendLine(message.IsNotNull() ? message.ToString() : string.Empty);
            if(ex.IsNotNull())
            {
                sb.Append("[Exception] ").AppendLine(ex.Message)
                  .Append("[Type] ").AppendLine(ex.GetType().ToString())
                  .Append("[Source] ").AppendLine(ex.Source)
                  .Append("[Stack] ").AppendLine().AppendLine(ex.StackTrace);
                if(ex.InnerException.IsNotNull())
                {
                    sb.Append("[InnerException] ").AppendLine(ex.InnerException.Message)
                      .Append("[InnerType] ").AppendLine(ex.InnerException.GetType().ToString())
                      .Append("[InnerSource] ").AppendLine(ex.InnerException.Source)
                      .Append("[InnerStack] ").AppendLine().AppendLine(ex.InnerException.StackTrace);
                }
            }
            sb.AppendLine("-----------END-----------").AppendLine();

            return sb.ToString();
        }

        private static string FormatSqlTrace(object sqlTrace, IOperator logOperator)
        {
            ArgumentHelper.Instance.CheckNull(sqlTrace);

            if(logOperator.IsNull())
            {
                logOperator = SystemLogOperator;
            }

            var sb = new StringBuilder()
                .Append(DateTime.Now.ToString("[HH:mm:ss.fff]"))
                .Append("[").Append(logOperator.Name).Append("]")
                .Append(sqlTrace);

            return sb.ToString();
        }
    }
}